﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Drawing.Drawing2D;
using System.IO;
using SkinSE;
using System.Runtime.InteropServices;
namespace MMDemo
{
    public partial class SysDataStructsForm : Form
    {
        [DllImport("user32.dll")]
        public static extern IntPtr SendMessage(IntPtr hwnd, int msg, int wParam, int lParam);
        [DllImport("User32.dll", EntryPoint = "FindWindow")]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        const int WM_SYSCOMMAND = 0x112;  
        const int SC_CLOSE = 0xF060;  
        const int SC_MINIMIZE = 0xF012;  
        const int SC_MAXIMIZE = 0xF030;  
        public SkinSE_Net skin;

        InterfaceNewData newDatainterface;
        /// <summary>
        /// 数据结构的接口
        /// </summary>
        private InterfaceDataStructs StructsInterface = null;
        /// <summary>
        /// 动画演示的线程
        /// </summary>
        public static Thread AnimationThread;
        private bool InitFlag = false;
        private bool stopfalage = false;
        private bool IsOnOffThread = false;
        /// <summary>
        /// 方便修改Enable的值
        /// </summary>
        private Button[] btns;

        public string strCurrentid;
        public SysDataStructsForm()
        {
            SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
            skin = new SkinSE_Net();
            skin.LoadSkinResourceFromFolder("iTools");
            skin.SubclassFrameEx(this.Handle, "mainFrame");
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void StructsForm_Load(object sender, EventArgs e)
        {
            CopyButtons();
           // DetachSkinSharp();
            SetTitleBackground(8);
            SetButtonsStyle();
            this.WindowState = FormWindowState.Minimized;
            this.WindowState = FormWindowState.Maximized;
            this.algorithmCtrl1.Width = this.Width * 2 / 5 - 5;
            this.algorithmCtrl1.Left = this.Width * 3 / 5 - 5;
            this.Animation_PicBox.Width = this.Width * 3 / 5 - 15;
            ShowAnimationAndAlgorithmCtr(false);
            InitDataStructsType();
            ReadCode();
            ChangeButtonsEnable(new int[] { 1, 2, 3, 4, 5, 6 });
        }
        private void SetButtonsStyle()
        {
            skin.SubclassWindowEx(btn_new.Handle, 2005, "btn.app.new");
            skin.SubclassWindowEx(btn_pause.Handle, 2005, "btn.app.pause");
            skin.SubclassWindowEx(btn_excute.Handle, 2005, "btn.app.excute");
            skin.SubclassWindowEx(btn_step.Handle, 2005, "btn.app.step");
            skin.SubclassWindowEx(btn_reset.Handle, 2005, "btn.app.reset");
            skin.SubclassWindowEx(btn_breakpoint.Handle, 2005, "btn.app.breakpoint");
            skin.SubclassWindowEx(btn_set.Handle, 2005, "btn.app.set");
            skin.SubclassWindowEx(btn_explain.Handle, 2005, "btn.app.explain");
            skin.SubclassWindowEx(btn_close.Handle, 2005, "btn.app.close");

            skin.SubclassWindowEx(btn_skin.Handle, 2005, "btn.change.skin");
        }

        const int WM_NCLBUTTONDOWN = 0x00A1;
        const int HTCAPTION = 2;

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_NCLBUTTONDOWN && m.WParam.ToInt32() == HTCAPTION)
            {
                return;
            }
            if (m.Msg == 0xA3)//双击标题栏
            {

                return;
            }
            base.WndProc(ref m);
        }


        private void btn_close_Click(object sender, EventArgs e)
        {
            if (AnimationThread != null)
            {
                try
                {
                    AnimationThread.Abort();
                }
                catch
                {
                    AnimationThread.Resume();
                    AnimationThread.Abort();
                }
            }
            this.Close();
        }

        private void btn_new_Click(object sender, EventArgs e)
        {
            switch (PublicDataClass.functionflag / 10)
            {
                case 1: newDatainterface = new NewListData(); break;//顺序表
                case 2: newDatainterface = new NewLinkData(); break;//链表
                case 3: newDatainterface = new NewQueueData(); break;//队列
                case 4: newDatainterface = new NewStackData(); break;//栈
                case 5: newDatainterface = new NewBinTreeData(); break;//二叉树
                case 6: newDatainterface = new NewGraphsData(); break;//图论
                case 7: newDatainterface = new NewSortData(); break;//排序
                case 8: newDatainterface = new NewSearchData(); break;//查找
                case 9: newDatainterface = new NewTreeData(); break;//查找
            }
            if (!newDatainterface.NewData())
            {
            return;
            }
            StructsInterface.InitData();
            ShowAnimationAndAlgorithmCtr(true);
            //初始化完后，只有暂停不能点击
            ChangeButtonsEnable(new int[] { 1 });
            InitFlag = true;
            stopfalage = false;
            IsOnOffThread = false;
        }
        public void OnOffThread()
        {
            if (!AnimationThread.IsAlive)
            {
                InitFlag = true;
                return;
            }
            if (stopfalage == false)
            {
                //AnimationThread.Suspend();
                stopfalage = true;
            }
            
            IsOnOffThread = true;
            ChangeButtonsEnable(new int[] {0, 1, 2 ,3 ,4, 5, 6, 7});
            if (PublicDataClass.IsSearchForIndex)
            {
                if (AnimationThread.IsAlive)
                {
                    AnimationThread.Suspend();
                    stopfalage = false;
                    ChangeButtonsEnable(new int[] { 1 });
                }
            }
        }
        private void btn_pause_Click(object sender, EventArgs e)
        {
            OnOffThread();
        }
        private void Excute()
        {
            AnimationThread = new Thread(new ThreadStart(StructsInterface.Animation));
            AnimationThread.Start();
        }
        private void btn_excute_Click(object sender, EventArgs e)
        {
            PublicDataClass.IsSingleStep = false;
            if (InitFlag)
            {
                InitFlag = false;
                Excute();
            }
            else if (AnimationThread.IsAlive)
            {
                AnimationThread.Resume();
                stopfalage = false;
            }
            ChangeButtonsEnable(new int[] { 0, 2, 3, 4, 5, 6, 7 });
        }

        private void btn_step_Click(object sender, EventArgs e)
        {
            ChangeButtonsEnable(new int[] {0, 1,2, 3,4,5,6,7 });
            PublicDataClass.IsSingleStep = true;
            if (InitFlag)
            {
                Excute();
                InitFlag = false;
            }
            else if (AnimationThread.IsAlive)
            {
                AnimationThread.Resume();
            }
        }

        private void btn_reset_Click(object sender, EventArgs e)
        {
            StructsInterface.ResetData();
            ChangeButtonsEnable(new int[] { 1 });
            stopfalage = false;
            IsOnOffThread = false;
            InitFlag = true;
        }
        private void btn_breakpoint_Click(object sender, EventArgs e)
        {
            ClearAllBreakPoint();
        }
        private void btn_set_Click(object sender, EventArgs e)
        {
            SysSetUpForm ssf = new SysSetUpForm();
            ssf.ShowDialog();
            StructsInterface.SetSpeed(PublicDataClass.scale);
        }

        private void btn_explain_Click(object sender, EventArgs e)
        {
            try
            {
                int func = PublicDataClass.functionflag;
                PublicDataClass.explainurl = Application.StartupPath +  "/explain/" + func.ToString() + ".txt";
                StreamReader objReader = new StreamReader(PublicDataClass.explainurl);
                SysExplainForm exp = new SysExplainForm();
                exp.ShowDialog();
            }
            catch
            {
                MessageBox.Show("未找到说明文件！");
            }  
        }
        private void ShowAnimationAndAlgorithmCtr(bool bShow)
        {
            Animation_PicBox.Visible = bShow;
            algorithmCtrl1.Visible = bShow;
            pictureBox1.Visible = !bShow;
        }
        private void InitDataStructsType()
        {
            if (null == StructsInterface)
            {
                this.Animation_PicBox.Image = PublicDataClass.DemoPicture;
                this.Animation_PicBox.SizeMode = PictureBoxSizeMode.StretchImage;
                switch (PublicDataClass.functionflag / 10)
                {
                    case 1: StructsInterface = new AnimationList(this, new DrawHandler(RefreshPictureBox), Animation_PicBox.Width,
                                                 Animation_PicBox.Height); break;
                    case 2: StructsInterface = new AnimationLink(this, new DrawHandler(RefreshPictureBox), Animation_PicBox.Width,
                                               Animation_PicBox.Height); break;//利用构造函数传递演示框的信息
                    case 3: StructsInterface = new AnimationQueue(this, new DrawHandler(RefreshPictureBox), Animation_PicBox.Width,
                                           Animation_PicBox.Height); break;
                    case 4: StructsInterface = new AnimationStack(this, new DrawHandler(RefreshPictureBox), Animation_PicBox.Width,
                                           Animation_PicBox.Height); break;
                    case 5: StructsInterface = new AnimationBinTree(this, new DrawHandler(RefreshPictureBox), Animation_PicBox.Width,
                                               Animation_PicBox.Height); break;
                    case 6: StructsInterface = new AnimationGraphs(this, new DrawHandler(RefreshPictureBox), Animation_PicBox.Width,
                                                  Animation_PicBox.Height); break;
                    case 7: StructsInterface = new AnimationSort(this, new DrawHandler(RefreshPictureBox), Animation_PicBox.Width,
                                              Animation_PicBox.Height); break;
                    case 8: StructsInterface = new AnimationSearch(this, new DrawHandler(RefreshPictureBox), Animation_PicBox.Width,
                                          Animation_PicBox.Height); break;
                    case 9: StructsInterface = new AnimationTree(this, new DrawHandler(RefreshPictureBox), Animation_PicBox.Width,
                                      Animation_PicBox.Height); break;
                }
            }
        }
        public void RefreshPictureBox()
        {
            Animation_PicBox.Refresh();
        }
        /// <summary>
        /// 设置算法框中选中的行
        /// </summary>
        public  void SetSelectLine(int line)
        {
            if (line == algorithmCtrl1.GetSelectLine())
            {
                return;
            }

            algorithmCtrl1.SetSelectLine(line);
            algorithmCtrl1.Refresh();
            if (algorithmCtrl1.FindBreakPoint(line) || PublicDataClass.IsSingleStep || stopfalage)
            {
                if (PublicDataClass.IsSingleStep)
                {
                    ChangeButtonsEnable(new int[] { 1 });
                }
                else
                {
                    ChangeButtonsEnable(new int[]{ 1, 5});
                }
                AnimationThread.Suspend();
                if (stopfalage)
                {
                    stopfalage = false;
                    ChangeButtonsEnable(new int[] { 1 });
                }
            }
        }
        /// <summary>
        /// 清空断点
        /// </summary>
        public void ClearAllBreakPoint()
        {
            algorithmCtrl1.ClearAllBreakPoint();
            algorithmCtrl1.Refresh();
        }
        private void ReadCode()
        {
            int func = PublicDataClass.functionflag;
            int langvage = PublicDataClass.languageflag;
            string codeurl = Application.StartupPath + "/code/" + langvage.ToString() + "_" + func.ToString() + ".txt";
            algorithmCtrl1.ReadAlgorithmFromFile(codeurl);    
        }

        private void Animation_PicBox_Paint(object sender, PaintEventArgs e)
        {
            if (null == StructsInterface)
            {
                return;
            }
            e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
            e.Graphics.DrawImage(StructsInterface.GetBufferBmp(),
            Animation_PicBox.ClientRectangle,
            Animation_PicBox.ClientRectangle,
           GraphicsUnit.Pixel);
        }
        public void ChangeButtonsEnable(int[] index)
        {
            for (int i = 0; i < 8; ++i)
            {
                    btns[i].Enabled = true;
            }
            for (int j = 0; j < index.Length; ++j)
            {
                btns[index[j]].Enabled = false;
            }
        }
        private void CopyButtons()
        {
            btns = new Button[8];
            btns[0] = btn_new;
            btns[1] = btn_pause;
            btns[2] = btn_excute;
            btns[3] = btn_step;
            btns[4] = btn_reset;
            btns[5] = btn_breakpoint;
            btns[6] = btn_set;
            btns[7] = btn_explain;
            
        }
        public void ChangeExcuteOverBtnsEnable()
        {
            ChangeButtonsEnable(new int[] { 1, 2, 3 });
        }

        private void DetachSkinSharp()
        {
            SysMainForm.skinh.DetachEx(this.Handle);
            for (int i = 0; i < btns.Length; ++i)
            {
                SysMainForm.skinh.DetachEx(btns[i].Handle);
            }
            SysMainForm.skinh.DetachEx(btn_close.Handle);
            SysMainForm.skinh.DetachEx(btn_skin.Handle);
        }
        private void btn_skin_Click(object sender, EventArgs e)
        {
            SysSkinForm f1 = new SysSkinForm(this);
            Point p = this.btn_skin.Location;
            p.Offset(this.Location);
            p.X -= f1.Width;
            p.Y += this.btn_skin.Size.Height;
            f1.StartPosition = FormStartPosition.Manual;
            f1.Location = p;
            f1.ShowDialog();
        }

        public void SetTitleBackground(int nIndex)
        {
            String strId;
            strId = "title.bk." + nIndex.ToString();
            skin.DirectUI_SetSubItemVisible(this.Handle, strId, 1, 0);
            skin.DirectUI_SetSubItemVisible(this.Handle, strCurrentid, 0, 1);
            strCurrentid = strId;
            skin.UpdateChildControlSkin(this.Handle);
        }
    }
}
